baubs git
Commit bd80e950044f54f40a60e710f22868f9dd93fafa
Parents : 365b0c7
Author : Jan-Henrik Bruhn <jan-henrik.bruhn@offis.de>
Date : 2025-12-20T15:44:51+01:00
feature: Migrate SkeletonLoader and PatternSummaryCard to shadcn/ui
- Replace SkeletonLoader with shadcn Skeleton component
- Simplify gradient animation to use shadcn's built-in pulse
- Migrate PatternSummaryCard to shadcn Card and Button
- Replace custom delete button with shadcn Button (outline variant)
- Use Loader2 from lucide-react for loading spinner
Code reduction:
- SkeletonLoader: Removed 8 lines of custom gradient classes
- Delete button: ~70% reduction (200+ char className → cleaner Button)
- Card wrapper: Semantic Card structure vs verbose div classes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes
2 files changed, 45 insertions(+), 57 deletions(-)
Diff
diff --git a/src/components/PatternSummaryCard.tsx b/src/components/PatternSummaryCard.tsx
index d06cf5e..d80773f 100644
--- a/src/components/PatternSummaryCard.tsx
+++ b/src/components/PatternSummaryCard.tsx
@@ -4,6 +4,9 @@ import { usePatternStore } from "../stores/usePatternStore";
import { canDeletePattern } from "../utils/machineStateHelpers";
import { PatternInfo } from "./PatternInfo";
import { DocumentTextIcon, TrashIcon } from "@heroicons/react/24/solid";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent } from "@/components/ui/card";
+import { Loader2 } from "lucide-react";
export function PatternSummaryCard() {
// Machine store
@@ -27,61 +30,46 @@ export function PatternSummaryCard() {
const canDelete = canDeletePattern(machineStatus);
return (
- <div className="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md border-l-4 border-primary-600 dark:border-primary-500">
- <div className="flex items-start gap-3 mb-3">
- <DocumentTextIcon className="w-6 h-6 text-primary-600 dark:text-primary-400 flex-shrink-0 mt-0.5" />
- <div className="flex-1 min-w-0">
- <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-1">
- Active Pattern
- </h3>
- <p
- className="text-xs text-gray-600 dark:text-gray-400 truncate"
- title={currentFileName}
- >
- {currentFileName}
- </p>
+ <Card className="border-l-4 border-primary-600 dark:border-primary-500">
+ <CardContent className="p-4">
+ <div className="flex items-start gap-3 mb-3">
+ <DocumentTextIcon className="w-6 h-6 text-primary-600 dark:text-primary-400 flex-shrink-0 mt-0.5" />
+ <div className="flex-1 min-w-0">
+ <h3 className="text-sm font-semibold text-gray-900 dark:text-white mb-1">
+ Active Pattern
+ </h3>
+ <p
+ className="text-xs text-gray-600 dark:text-gray-400 truncate"
+ title={currentFileName}
+ >
+ {currentFileName}
+ </p>
+ </div>
</div>
- </div>
- <PatternInfo pesData={pesData} />
+ <PatternInfo pesData={pesData} />
- {canDelete && (
- <button
- onClick={deletePattern}
- disabled={isDeleting}
- className="w-full flex items-center justify-center gap-2 px-3 py-2.5 sm:py-2 bg-danger-50 dark:bg-danger-900/20 text-danger-700 dark:text-danger-300 rounded border border-danger-300 dark:border-danger-700 hover:bg-danger-100 dark:hover:bg-danger-900/30 text-sm font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
- >
- {isDeleting ? (
- <>
- <svg
- className="w-3 h-3 animate-spin"
- fill="none"
- viewBox="0 0 24 24"
- >
- <circle
- className="opacity-25"
- cx="12"
- cy="12"
- r="10"
- stroke="currentColor"
- strokeWidth="4"
- ></circle>
- <path
- className="opacity-75"
- fill="currentColor"
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
- ></path>
- </svg>
- Deleting...
- </>
- ) : (
- <>
- <TrashIcon className="w-3 h-3" />
- Delete Pattern
- </>
- )}
- </button>
- )}
- </div>
+ {canDelete && (
+ <Button
+ onClick={deletePattern}
+ disabled={isDeleting}
+ variant="outline"
+ className="w-full bg-danger-50 dark:bg-danger-900/20 text-danger-700 dark:text-danger-300 border-danger-300 dark:border-danger-700 hover:bg-danger-100 dark:hover:bg-danger-900/30"
+ >
+ {isDeleting ? (
+ <>
+ <Loader2 className="w-3 h-3 animate-spin" />
+ Deleting...
+ </>
+ ) : (
+ <>
+ <TrashIcon className="w-3 h-3" />
+ Delete Pattern
+ </>
+ )}
+ </Button>
+ )}
+ </CardContent>
+ </Card>
);
}
diff --git a/src/components/SkeletonLoader.tsx b/src/components/SkeletonLoader.tsx
index a7447c9..a69a655 100644
--- a/src/components/SkeletonLoader.tsx
+++ b/src/components/SkeletonLoader.tsx
@@ -1,3 +1,6 @@
+import { Skeleton } from "@/components/ui/skeleton";
+import { cn } from "@/lib/utils";
+
interface SkeletonLoaderProps {
className?: string;
variant?: "text" | "rect" | "circle";
@@ -7,9 +10,6 @@ export function SkeletonLoader({
className = "",
variant = "rect",
}: SkeletonLoaderProps) {
- const baseClasses =
- "animate-pulse bg-gradient-to-r from-gray-200 via-gray-300 to-gray-200 dark:from-gray-700 dark:via-gray-600 dark:to-gray-700 bg-[length:200%_100%]";
-
const variantClasses = {
text: "h-4 rounded",
rect: "rounded-lg",
@@ -17,7 +17,7 @@ export function SkeletonLoader({
};
return (
- <div className={`${baseClasses} ${variantClasses[variant]} ${className}`} />
+ <Skeleton className={cn(variantClasses[variant], className)} />
);
}
Served by rngit 1.3.3 - Generated in 0.05s